package com.zhkj.txg.module.cart.adapter

import android.graphics.Paint
import android.text.TextUtils
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.CheckBox
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.chad.library.adapter.base.BaseNodeAdapter
import com.chad.library.adapter.base.entity.node.BaseNode
import com.chad.library.adapter.base.provider.BaseNodeProvider
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.zhkj.lib.utils.AccountManager
import com.zhkj.lib.utils.SpanUtil
import com.zhkj.txg.R
import com.zhkj.txg.module.cart.entity.CartProductEntity
import com.zhkj.txg.module.cart.entity.CartSelectedEntity
import com.zhkj.txg.module.cart.entity.CartShopEntity
import com.zhkj.txg.module.home.ui.ShopActivity
import com.zhkj.txg.utils.ImageUtils
import com.zhkj.txg.utils.TextWatcherWrapper
import com.mcxtzhang.swipemenulib.SwipeMenuLayout
import razerdp.util.KeyboardUtils.close
import razerdp.util.KeyboardUtils.isOpen
import java.math.BigDecimal

class CartAdapter(
    val listener: OnCartItemSelectedListener? = null
) : BaseNodeAdapter() {

    companion object {
        val TYPE_SHOP = 0
        val TYPE_PRODUCT = 1
    }

    init {
        addFullSpanNodeProvider(CartShopProvider())
        addNodeProvider(CartProductProvider(listener))
    }

    val checkStatusEntity = CartSelectedEntity()

    override fun getItemType(data: List<BaseNode>, position: Int): Int {
        return when (data[position]) {
            is CartShopEntity -> TYPE_SHOP
            is CartProductEntity -> TYPE_PRODUCT
            else -> TYPE_SHOP
        }
    }

    /**
     * 刷新选中状态的entity
     * @param needAllCheck 是否需要进行全部选中、取消全选操作
     * @param allCheck 全部选中、取消全选
     */
    fun refreshStatusEntity(
        needAllCheck: Boolean = false,
        allCheck: Boolean = false,
        cartId: Long = 0,
        number: Int = 0,
        ignoreOnSale: Boolean
    ): CartSelectedEntity {
        var initPrice = BigDecimal(0.0)
        checkStatusEntity.allSelected = true
        checkStatusEntity.selectAny = false
        for (product in data) (product as? CartProductEntity)?.let {
            // 设置是否全选,排除下架商品
            if (needAllCheck && (it.isGoodsOnSale() || ignoreOnSale)) it.selected = allCheck
            // 判断是否需要修改商品数量
            if (cartId == it.cartId) it.goodsNumber = number
            // 计算总价,排除下架商品
            if (it.selected && it.isGoodsOnSale()) initPrice = initPrice.add(
                BigDecimal(it.goodsPrice).multiply(BigDecimal(it.goodsNumber))
            )
            // 判断是否全选、选中状态,排除下架商品
            if (it.isGoodsOnSale() || ignoreOnSale) {
                if (!it.selected) checkStatusEntity.allSelected = false
                else checkStatusEntity.selectAny = true
            }
        }
        if (needAllCheck || (cartId > 0 && number > 0)) notifyDataSetChanged()
        checkStatusEntity.totalPrice = initPrice.toString()
        return checkStatusEntity
    }

    /**
     * 获取所有已选择的商品购物车id，用,隔开
     */
    fun getCartIds(): String {
        val builder = StringBuilder()
        for (product in data) (product as? CartProductEntity)?.let {
            if (it.selected) builder.append(it.cartId).append(",")
        }
        if (builder.isNotEmpty()) builder.deleteCharAt(builder.lastIndex)
        return builder.toString()
    }
}

class CartShopProvider : BaseNodeProvider() {
    override val itemViewType: Int = CartAdapter.TYPE_SHOP
    override val layoutId: Int = R.layout.item_cart_shop

    override fun convert(helper: BaseViewHolder, data: BaseNode) {
        (data as? CartShopEntity)?.let {
            val imageView = helper.setText(R.id.tvCartShopName, data.shopName)
                .getView<ImageView>(R.id.ivCartShop)
            ImageUtils.loadCircleImage(context, imageView, data.shopImg)
        }
    }

    override fun onClick(helper: BaseViewHolder, view: View, data: BaseNode, position: Int) {
        (data as? CartShopEntity)?.let {
            if (it.shopId > 0) ShopActivity.open(context, it.shopName, it.shopId)
        }
    }
}

class CartProductProvider(
    val listener: OnCartItemSelectedListener?
) : BaseNodeProvider() {
    override val itemViewType: Int = CartAdapter.TYPE_PRODUCT
    override val layoutId: Int = R.layout.item_cart_product

    init {
        addChildClickViewIds(R.id.cbCartCheck, R.id.viewProduct, R.id.tvDelete)
    }

    override fun onViewHolderCreated(viewHolder: BaseViewHolder, viewType: Int) {
        viewHolder.getView<EditText>(R.id.etNum).let {
            it.addTextChangedListener(TextWatcherWrapper { s ->
                if (s.isNullOrEmpty()) it.setText("0")
                else if (s.length > 1 && s.startsWith('0')) s.delete(0, 1)
                else if (
                    (getAdapter()?.data?.get(viewHolder.layoutPosition) as? CartProductEntity)?.storeCount ?: 9999 <
                    s.toString().toInt()
                ) s.replace(
                    0, s.length,
                    (((getAdapter()?.data?.get(viewHolder.layoutPosition) as? CartProductEntity)?.storeCount
                        ?: 9999).toString())
                )
                it.setSelection(it.text.length)
            })
            it.setOnEditorActionListener { _, actionId, _ ->
                (actionId == EditorInfo.IME_ACTION_DONE).apply {
                    val numOrNull = it.text.toString()
                    listener?.numberChange(
                        viewHolder.layoutPosition, 2,
                        if (numOrNull.isEmpty()) 0 else numOrNull.toInt(),
                        (getAdapter()?.data?.get(viewHolder.layoutPosition) as? CartProductEntity)?.storeCount ?: 9999
                    )
                    if (this && it.hasFocus()) it.clearFocus()
                    if (isOpen()) close(it)
                }
            }
            it.setOnFocusChangeListener { _, hasFocus ->
                if (!hasFocus && isOpen()) close(it)
            }
        }
    }

    override fun convert(helper: BaseViewHolder, data: BaseNode) {
        (data as? CartProductEntity)?.let { item ->
            val imageView = helper.setText(R.id.tvCartProductName, item.goodsName)
                .setText(
                    R.id.tvCartProductSpec,
                    if (item.specName.isEmpty()) context.getString(R.string.default_spec_value) else item.specName
                )
                .setText(R.id.tvCartProductPrice, SpanUtil.setMoneySymbol(item.goodsPrice, true))
                .setText(R.id.etNum, item.goodsNumber.toString())
                .setGone(R.id.tvCartProductTag, !TextUtils.equals(item.isNew, "1"))
                .setGone(R.id.viewCartMask, item.isGoodsOnSale())
                .setGone(R.id.tvMask, item.isGoodsOnSale())
                .getView<ImageView>(R.id.ivCartShopProduct)
            ImageUtils.loadRoundCornerImage(context, imageView, item.image)
            helper.getView<CheckBox>(R.id.cbCartCheck).isChecked = item.selected
            // 设置是显示市场价还是显示分享赚多少钱
            helper.getView<TextView>(R.id.tvCartProductEarn).apply {
                if (AccountManager.isMember() && item.shareEarn.isNotEmpty() && item.shareEarn != "0") {
                    setTextColor(ContextCompat.getColor(context, R.color.colorMain))
                    paint.flags = Paint.ANTI_ALIAS_FLAG
                    text = SpanUtil.setPrefixMoneyStr(price = item.shareEarn)
                } else {
                    setTextColor(ContextCompat.getColor(context, R.color.colorLightText))
                    paint.flags = Paint.STRIKE_THRU_TEXT_FLAG
                    paint.isAntiAlias = true
                    text = SpanUtil.setMoneySymbol(item.marketPrice)
                }
            }
            val etNum = helper.getView<EditText>(R.id.etNum)
            // 减号按钮监听
            helper.getView<View>(R.id.tvMinus).takeUnless { it.hasOnClickListeners() }?.setOnClickListener {
                etNum.clearFocus()
                if (isOpen()) close(etNum)
                val numOrNull = etNum.text?.toString()
                listener?.numberChange(
                    helper.layoutPosition, 0,
                    if (!numOrNull.isNullOrEmpty()) numOrNull.toInt() else 0,
                    item.storeCount ?: 9999
                )
            }
            // 加号按钮监听
            helper.getView<View>(R.id.tvPlus).takeUnless { it.hasOnClickListeners() }?.setOnClickListener {
                etNum.clearFocus()
                val numOrNull = etNum.text?.toString()
                if (isOpen()) close(etNum)
                listener?.numberChange(
                    helper.layoutPosition, 1,
                    if (!numOrNull.isNullOrEmpty()) numOrNull.toInt() else 0,
                    item.storeCount ?: 9999
                )
            }
        }
    }

    override fun onChildClick(helper: BaseViewHolder, view: View, data: BaseNode, position: Int) {
        (data as? CartProductEntity)?.let {
            when (view.id) {
                // 选中购物车商品
                R.id.cbCartCheck -> {
                    it.selected = !it.selected
                    listener?.changed()
                }
                // 点击商品
                R.id.viewProduct -> {
                    listener?.itemClick(position, it)
//                    ProductDetailActivity.normalProduct(context, it.goodsId, true)
                }
                // 删除按钮
                R.id.tvDelete -> {
                    helper.getView<SwipeMenuLayout>(R.id.viewSwipe).quickClose()
                    listener?.itemDelete(position)
                }
                else -> Unit
            }
        }
    }
}

interface OnCartItemSelectedListener {
    /**
     * 选中状态发生变化
     */
    fun changed()

    /**
     * 数量变化
     * @param uiPosition 在adapter上面的位置
     * @param type 类型 0:减 1:加 2:数量
     * @param originNumber 点击时的数字
     * @param maxCount 最大值(库存)
     */
    fun numberChange(uiPosition: Int, type: Int, originNumber: Int, maxCount: Int)

    /**
     * 侧滑删除购物车商品
     */
    fun itemDelete(uiPosition: Int)

    /**
     * 点击事件
     */
    fun itemClick(uiPosition: Int, product: CartProductEntity)
}